home *** CD-ROM | disk | FTP | other *** search
- From:
- Peter Below
- Geisenheimer Str. 88
- D60529 Frankfurt am Main
- Germany
-
- To:
- Nathan Wallace
- 530 Meadowlark Drive
- Lakewood, CO 80226
- U.S.A.
-
-
-
-
- Dynamic Arrays in Delphi
- ========================
-
- This archive should contain the following files:
-
- readme.txt This file
- arrays.hlp Help file describing the array classes
- arrays.pas Unit implementing the array classes
- fastmem.pas Auxillary Unit used by Arrays.PAS, see helpfile
- multidim.pas Bonus Unit with a bare-bones multidimensional
- array class.
- arrtest.dpr Project file for the test program
- arrtest1.dfm Main form of the test program
- arrtest2.dfm Secondary form
- arrtest3.dfm "
- arrtest4.dfm "
- arrtest5.dfm "
- arrtest6.dfm "
- arrtest7.dfm "
- arrtest8.dfm "
- arrtest1.pas Main Unit of the the test program
- arrtest2.pas Secondary unit
- arrtest3.pas "
- arrtest4.pas "
- arrtest5.pas "
- arrtest6.pas "
- arrtest7.pas "
- arrtest8.pas "
-
- Author
- ======
-
- Dr. Peter Below
- e-mail: CIS 100113,1101
- Internet: 100113.1101@compuserve.com (preferred)
- below@msmrd.frankfurt.hoechst-ag.d400.de
-
- This code is freeware and released to the public domain. You may use
- it as you see fit in your own applications and distribute it as part
- of an application without royalties. You may also distribute the
- source code in this archive, preferrable in form of this archive,
- provided that you give due credit to the author, include this section
- of the readme file unchanged, and don't charge more for it than is
- warranted by the cost of media and distribution per se.
-
- I give no warranties as to the proper functioning of the code in this
- archive. It has been tested under both Delphi 1.0 and Delphi 2.0 and
- i'm not aware of any problems with it. However, that does not
- guarantee that none exist, and i will not take responsibilty or
- provide compensation for any damage done to software, data, hardware,
- personal, lifestock, buildings, and the rest of the pyhsical and
- spiritual world as a consequence of errors in this code!
-
- Installation
- ============
-
- The only files you need for using the array classes are arrays.pas
- and fastmem.pas, copy these to a directory on your harddisk that is
- on the LIB search path you have set in Delphi. You will probably also
- want to use the help file, so copy arrays.hlp to a directory of your
- choice and create a icon for it in your favourite program manager
- group. There's no provision to integrate this helpfile into the
- Delphi help system, sorry, you have to open and search it manually
- (or use a proper editor like CodeWright, that can extract the
- keywords from the helpfile itself <g>).
-
- If you want to try the test program, copy the arrtest*.* files to a
- directory on the harddisk, open the arrtest.dpr project and compile
- it. The forms have been developed on 1024*768 large font video, i
- hope they scale correctly on other resolutions. The test program just
- shows how to use several of the array classes and features like
- resize, sort and clone. It has no associated documentation, just play
- around with it.
-
- Description
- ===========
-
- Arrays as implemented in Borland's Pascal dialect (and the Pascal
- standard as defined by Wirth) are declared at compile time. If you
- need to allocate an array with a size only known at run time the only
- option is to use a pointer to a large array type and only allocate as
- much memory as needed:
-
- Type
- TDoubleArray = Array [0..High(Word) div Sizeof(Double) - 1] of Double;
- PDoubleArray = ^TDoubleArray;
-
- Var
- pMyArray : PDoubleArray;
- i, numItems : Integer;
- Begin
- numItems := 200;
- GetMem( pMyArray, numItems * Sizeof(Double));
- For i:= 0 To Pred(numItems) Do
- pMyArray^[i] := ....
-
- Such a dynamically allocated array can also be resized with
- ReAllocMem. The main problem is keeping track of the actual upper
- bound of the array. This approach effectively disables range checking
- by the compiler since the type declaration for the array is what the
- compiler uses to determine the highest valid index in its range
- checking code. So you have to pass the actual size around with the
- pointer to the array wherever you use it and guard against range
- errors yourself. Combined with the issue of allocating and
- deallocating memory correctly and the use of pointers (deemed
- un-Pascalian by many) this is a source of errors that is hard to
- avoid. Writing reusable code with such a construct is not impossible
- but harder than it ought to be <g>.
-
- The natural approach with OOP available in Delphi is to encapsulate
- all this mess into a class and be done with it once and for all. This
- is what the ARRAYS.PAS unit in this archive does.
-
- Many of the tasks such an array class has to do are actually
- independent of the items it stores. These functionalities are thus
- implemented in a base class, TBaseArray. This class has methods to
- deal with data items on a rather abstract level. The only things it
- needs to know are the size of a data item and how many it has to
- store. That is enough to handle allocation and deallcoation of
- memory, to provide basic support for sorting, insertion, deletion,
- copying, to store and retrieve individual items. The class takes care
- of all memory management related items, keeps count of how many items
- it can store, does index range checking (if required), can be
- resized, cloned, assigned, stored to stream or disk and read from the
- same sources. Access to individual items requires method calls,
- however, the common array syntax cannot be used here.
-
- Specialized arrays for certain data types are derived from
- TBaseArray. The Arrays Unit already provides a couple of these types
- for the standard data types. These derived classes mainly do two
- things: provide the correct sort method for this data type and
- provide a Data property which allows access to items using the normal
- array syntax.
-
- There is a price for all this comfort: speed. Using objects entails a
- certain overhead. To access a method or field of an object the
- code has to load the address of the object first (indirect
- referencing). Accessing an array item via the Data property also
- involves a method call. The code has to execute more instructions to
- access an item in an array object than to access one in a normal
- array. This becomes rather noticeable in code that accesses all items
- of an array in sequence, e.g. a loop over all array items to do a
- sum. These can take 2-3 times as long with an array object. Using
- one of the iterator methods for such a task adds another method call
- and thus is even slower than a straight For loop using the Data
- property!
-
- In cases where speed is important it may pay to store the
- Memory-property to a pointer-to-an-array-type variable and then
- proceed as in the classical approach cited above.
-
- The array classes are limited to 64KBytes in Delphi 1.0 since they
- store all items in one contiguous memory block. This limit does not
- exist in Delphi 2.0. The array classes are also one-dimensional only.
- The sample class in MULTIDIM.PAS shows a possible approach to
- building multidimensional array classes on top of the one-dimensional
- ones in arrays.pas.
-
- Have fun with these units and don't hesitate to contact me if you
- have problems or questions.
-
- May 1996
- Peter Below
-